package com.edu.exam.entity.assessment.technical;

import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.experimental.Accessors;

import com.edu.exam.enums.common.AnomalyStatus;
import com.edu.exam.enums.common.SeverityLevel;
import com.edu.exam.enums.common.SourceModule;

import java.time.LocalDateTime;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

/**
 * 质量异常实体类
 * 所属模块：B-02 题库管理模块
 * 对应数据库表：quality_anomaly
 *
 * 根据E-06-03质量监控子模块设计实现
 * 对应quality_anomalies数据表，用于存储质量异常检测和处理的完整记录
 *
 * @author System
 * @version 1.0.0
 */
@Entity
@Data
@Builder
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class QualityAnomaly {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "anomaly_id", length = 32, unique = true, nullable = false)
    private String anomalyId;

    @Column(name = "evaluation_id", length = 32, nullable = false)
    private String evaluationId;

    @Enumerated(EnumType.STRING)
    @Column(name = "source_module", length = 20, nullable = false)
    private String sourceModule;

    @Column(name = "task_id", length = 32, nullable = false)
    private String taskId;

    @Column(name = "grader_id", length = 32, nullable = false)
    private String graderId;

    @Column(name = "anomaly_type", length = 50, nullable = false)
    private String anomalyType;

    @Enumerated(EnumType.STRING)
    @Column(name = "severity", length = 20, nullable = false)
    private SeverityLevel severity;

    @Column(name = "description", columnDefinition = "TEXT", nullable = false)
    private String description;

    @Column(name = "anomaly_data", columnDefinition = "JSON")
    private String anomalyData;

    @Column(name = "detection_rule", length = 100)
    private String detectionRule;

    @Enumerated(EnumType.STRING)
    @Column(name = "status", length = 20, nullable = false)
    private AnomalyStatus status;

    @Column(name = "detected_at", nullable = false)
    private LocalDateTime detectedAt;

    @Column(name = "acknowledged_by", length = 32)
    private String acknowledgedBy;

    @Column(name = "acknowledged_at")
    private LocalDateTime acknowledgedAt;

    @Column(name = "resolved_by", length = 32)
    private String resolvedBy;

    @Column(name = "resolved_at")
    private LocalDateTime resolvedAt;

    @Column(name = "resolution_notes", columnDefinition = "TEXT")
    private String resolutionNotes;

    // 扩展字段
    @Column(name = "anomaly_category", length = 50)
    private String anomalyCategory; // 异常分类

    @Column(name = "anomaly_subcategory", length = 50)
    private String anomalySubcategory; // 异常子分类

    @Column(name = "anomaly_score", precision = 5, scale = 4)
    private Double anomalyScore; // 异常评分

    @Column(name = "confidence_score", precision = 3, scale = 2)
    private Double confidenceScore; // 置信度评分

    @Column(name = "impact_level", length = 20)
    private String impactLevel; // 影响级别

    @Column(name = "urgency_level", length = 20)
    private String urgencyLevel; // 紧急程度

    @Column(name = "risk_level", length = 20)
    private String riskLevel; // 风险级别

    @Column(name = "detection_method", length = 50)
    private String detectionMethod; // 检测方法

    @Column(name = "detection_algorithm", length = 100)
    private String detectionAlgorithm; // 检测算法

    @Column(name = "detection_version", length = 10)
    private String detectionVersion; // 检测版本

    @Column(name = "detection_confidence", precision = 3, scale = 2)
    private Double detectionConfidence; // 检测置信度

    @Column(name = "baseline_value", precision = 10, scale = 4)
    private Double baselineValue; // 基准值

    @Column(name = "observed_value", precision = 10, scale = 4)
    private Double observedValue; // 观测值

    @Column(name = "deviation_percentage", precision = 5, scale = 2)
    private Double deviationPercentage; // 偏差百分比

    @Column(name = "threshold_value", precision = 10, scale = 4)
    private Double thresholdValue; // 阈值

    @Column(name = "threshold_type", length = 20)
    private String thresholdType; // 阈值类型

    @Column(name = "violation_count")
    private Integer violationCount; // 违规次数

    @Column(name = "historical_frequency", precision = 5, scale = 2)
    private Double historicalFrequency; // 历史频率

    @Column(name = "affected_entities", columnDefinition = "JSON")
    private String affectedEntities; // 受影响实体

    @Column(name = "affected_metrics", columnDefinition = "JSON")
    private String affectedMetrics; // 受影响指标

    @Column(name = "root_cause_analysis", columnDefinition = "JSON")
    private String rootCauseAnalysis; // 根因分析

    @Column(name = "potential_causes", columnDefinition = "JSON")
    private String potentialCauses; // 潜在原因

    @Column(name = "correlation_factors", columnDefinition = "JSON")
    private String correlationFactors; // 关联因子

    @Column(name = "mitigation_actions", columnDefinition = "JSON")
    private String mitigationActions; // 缓解措施

    @Column(name = "prevention_measures", columnDefinition = "JSON")
    private String preventionMeasures; // 预防措施

    @Column(name = "escalation_required")
    private Boolean escalationRequired; // 是否需要升级

    @Column(name = "escalation_level", length = 20)
    private String escalationLevel; // 升级级别

    @Column(name = "escalated_to", length = 32)
    private String escalatedTo; // 升级对象

    @Column(name = "escalated_at")
    private LocalDateTime escalatedAt; // 升级时间

    @Column(name = "escalation_reason", columnDefinition = "TEXT")
    private String escalationReason; // 升级原因

    @Column(name = "follow_up_required")
    private Boolean followUpRequired; // 是否需要跟进

    @Column(name = "follow_up_date")
    private LocalDateTime followUpDate; // 跟进日期

    @Column(name = "follow_up_assigned_to", length = 32)
    private String followUpAssignedTo; // 跟进负责人

    @Column(name = "follow_up_completed")
    private Boolean followUpCompleted; // 跟进是否完成

    @Column(name = "follow_up_completion_date")
    private LocalDateTime followUpCompletionDate; // 跟进完成日期

    @Column(name = "notification_sent")
    private Boolean notificationSent; // 是否已发送通知

    @Column(name = "notification_sent_at")
    private LocalDateTime notificationSentAt; // 通知发送时间

    @Column(name = "notification_recipients", columnDefinition = "JSON")
    private String notificationRecipients; // 通知接收者

    @Column(name = "notification_channels", columnDefinition = "JSON")
    private String notificationChannels; // 通知渠道

    @Column(name = "external_references", columnDefinition = "JSON")
    private String externalReferences; // 外部引用

    @Column(name = "related_anomalies", columnDefinition = "JSON")
    private String relatedAnomalies; // 相关异常

    @Column(name = "resolution_methods", columnDefinition = "JSON")
    private String resolutionMethods; // 解决方法

    @Column(name = "resolution_effectiveness", length = 20)
    private String resolutionEffectiveness; // 解决效果

    @Column(name = "lessons_learned", columnDefinition = "TEXT")
    private String lessonsLearned; // 经验教训

    @Column(name = "quality_improvement_suggestions", columnDefinition = "JSON")
    private String qualityImprovementSuggestions; // 质量改进建议

    @Column(name = "process_changes_required", columnDefinition = "JSON")
    private String processChangesRequired; // 流程变更需求

    @Column(name = "training_needs", columnDefinition = "JSON")
    private String trainingNeeds; // 培训需求

    @Column(name = "tool_adjustments", columnDefinition = "JSON")
    private String toolAdjustments; // 工具调整

    @Column(name = "reoccurrence_prevented")
    private Boolean reoccurrencePrevented; // 是否预防复发

    @Column(name = "verification_required")
    private Boolean verificationRequired; // 是否需要验证

    @Column(name = "verification_date")
    private LocalDateTime verificationDate; // 验证日期

    @Column(name = "verification_result", length = 20)
    private String verificationResult; // 验证结果

    @Column(name = "verified_by", length = 32)
    private String verifiedBy; // 验证人

    @Column(name = "archived")
    private Boolean archived; // 是否已归档

    @Column(name = "archive_date")
    private LocalDateTime archiveDate; // 归档日期

    @Column(name = "retention_days")
    private Integer retentionDays; // 保留天数

    @Column(name = "correlation_id", length = 100)
    private String correlationId; // 关联ID

    @Column(name = "batch_anomaly_id", length = 32)
    private String batchAnomalyId; // 批次异常ID

    @Column(name = "parent_anomaly_id", length = 32)
    private String parentAnomalyId; // 父异常ID

    @Column(name = "child_anomaly_ids", columnDefinition = "JSON")
    private String childAnomalyIds; // 子异常ID列表

    @PrePersist
    protected void onCreate() {
        LocalDateTime now = LocalDateTime.now();
        this.detectedAt = now;

        // 设置默认值
        if (this.status == null) {
            this.status = AnomalyStatus.DETECTED;
        }
        if (this.escalationRequired == null) {
            this.escalationRequired = false;
        }
        if (this.followUpRequired == null) {
            this.followUpRequired = false;
        }
        if (this.notificationSent == null) {
            this.notificationSent = false;
        }
        if (this.reoccurrencePrevented == null) {
            this.reoccurrencePrevented = false;
        }
        if (this.verificationRequired == null) {
            this.verificationRequired = true;
        }
        if (this.archived == null) {
            this.archived = false;
        }
        if (this.violationCount == null) {
            this.violationCount = 1;
        }
        if (this.detectionConfidence == null) {
            this.detectionConfidence = 1.0;
        }
    }

    // ===== 标准审计字段 =====

    /**
     * 创建时间（标准审计字段）
     */
    @CreationTimestamp
    @Column(name = "created_time_audit", nullable = false, updatable = false)
    private LocalDateTime createdTimeAudit;

    /**
     * 更新时间（标准审计字段）
     */
    @UpdateTimestamp
    @Column(name = "updated_time_audit", nullable = false)
    private LocalDateTime updatedTimeAudit;

    /**
     * 版本号（乐观锁）
     */
    @Version
    @Column(name = "version_audit")
    Long versionAudit = 0L;

    /**
     * 逻辑删除标记（标准审计字段）
     */
    @Column(name = "is_deleted_audit", nullable = false)
    Boolean isDeletedAudit = false;
}